<?php


use Phinx\Migration\AbstractMigration;

class FillCrmSchemaData extends AbstractMigration
{

    /**
     * 获取所有模块数据
     * @return array
     */
    public function getAllModuleData()
    {
        $sql = 'select * from module';
        $result = $this->query($sql);
        $info = array();
        foreach ($result as $key => $val) {
            $info[$val['code']] = $val;
        }
        return $info;
    }

    /**
     * 生成实体数据结构模板
     * @param $moduleCode
     * @param array $parentModuleConfig
     * @return array
     * @throws Exception
     */
    protected function generateEntitySchemaTemplate($moduleCode, $parentModuleConfig = ['child' => '', 'parent' => ''])
    {
        $schemaData = [
            'schema' => [
                'name' => ucfirst($moduleCode),
                'code' => $moduleCode,
                'type' => 'system',
                'uuid' => Webpatser\Uuid\Uuid::generate()->string
            ],
            'module_relation' => [
                [ // 关联项目
                    'src_module_code' => $moduleCode,
                    'dst_module_code' => 'project',
                    'type' => 'belong_to',
                    'link_id' => ['project_id']
                ],
                [ // 关联模块
                    'src_module_code' => $moduleCode,
                    'dst_module_code' => 'module',
                    'type' => 'belong_to',
                    'link_id' => ['module_id']
                ],
                [ // 关联用户
                    'src_module_code' => $moduleCode,
                    'dst_module_code' => 'user',
                    'type' => 'belong_to',
                    'link_id' => ['created_by']
                ],
                [ // 关联反馈
                    'src_module_code' => $moduleCode,
                    'dst_module_code' => 'note',
                    'type' => 'has_many',
                    'link_id' => ['link_id', 'module_id']
                ],
                [ // 关联任务
                    'src_module_code' => $moduleCode,
                    'dst_module_code' => 'task',
                    'type' => 'has_many',
                    'link_id' => ['entity_id', 'entity_module_id']
                ],
                [ // 关联工序流
                    'src_module_code' => $moduleCode,
                    'dst_module_code' => 'step_workflow',
                    'type' => 'belong_to',
                    'link_id' => ['step_workflow_id']
                ]
            ]
        ];


        if (!empty($parentModuleConfig['child'])) {
            // 所属 entity 子集
            array_unshift($schemaData['module_relation'], [
                'src_module_code' => $moduleCode,
                'dst_module_code' => $parentModuleConfig['child'],
                'type' => 'has_many',
                'link_id' => ['entity_id,entity_module_id']
            ]);
        }

        if (!empty($parentModuleConfig['other'])) {
            foreach ($parentModuleConfig['other'] as $otherItem) {
                $schemaData['module_relation'][] = $otherItem;
            }
        }

//        if (!empty($parentModuleConfig['parent'])) {
//            // 所属 entity 父级
//            array_unshift($schemaData['module_relation'], [
//                'src_module_code' => $moduleCode,
//                'dst_module_code' => $parentModuleConfig['parent'],
//                'type' => 'belong_to',
//                'link_id' => ['entity_id,entity_module_id']
//            ]);
//        }

        return $schemaData;
    }

    /**
     * Change Method.
     *
     * Write your reversible migrations using this method.
     *
     * More information on writing migrations is available here:
     * http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
     *
     * The following commands can be used in this method and Phinx will
     * automatically reverse them when rolling back:
     *
     *    createTable
     *    renameTable
     *    addColumn
     *    renameColumn
     *    addIndex
     *    addForeignKey
     *
     * Remember to call "create()" or "update()" and NOT "save()" when working
     * with the Table class.
     */

    /**
     * Migrate Up.
     * @throws Exception
     */
    public function up()
    {
        $moduleMap = $this->getAllModuleData();

        // 已经存在的关联模型
        $schemaConfig = [
            [
                'schema' => [
                    'name' => '订单模块模型',
                    'code' => 'order',
                    'type' => 'system',
                    'uuid' => Webpatser\Uuid\Uuid::generate()->string
                ],
                'module_relation' => [
                    [ // 订单所属工序分类
                        'src_module_code' => 'order',
                        'dst_module_code' => 'step_category',
                        'type' => 'belong_to',
                        'link_id' => ['step_category_id']
                    ],
                    [ // 订单所属项目
                        'src_module_code' => 'order',
                        'dst_module_code' => 'project',
                        'type' => 'belong_to',
                        'link_id' => ['project_id']
                    ],
                    [ // 订单创建用户
                        'src_module_code' => 'order',
                        'dst_module_code' => 'user',
                        'type' => 'belong_to',
                        'link_id' => ['created_by']
                    ]
                ]
            ],
            [
                'schema' => [
                    'name' => '合同模块模型',
                    'code' => 'contract',
                    'type' => 'system',
                    'uuid' => Webpatser\Uuid\Uuid::generate()->string
                ],
                'module_relation' => [
                    [ // 合同所属订单
                        'src_module_code' => 'contract',
                        'dst_module_code' => 'order',
                        'type' => 'belong_to',
                        'link_id' => ['order_id']
                    ],
                    [ // 合同所属项目
                        'src_module_code' => 'contract',
                        'dst_module_code' => 'project',
                        'type' => 'belong_to',
                        'link_id' => ['project_id']
                    ],
                    [ // 合同创建用户
                        'src_module_code' => 'contract',
                        'dst_module_code' => 'user',
                        'type' => 'belong_to',
                        'link_id' => ['created_by']
                    ]
                ]
            ],
            [
                'schema' => [
                    'name' => '回款计划模块模型',
                    'code' => 'receivable_plan',
                    'type' => 'system',
                    'uuid' => Webpatser\Uuid\Uuid::generate()->string
                ],
                'module_relation' => [
                    [ // 回款计划所属合同
                        'src_module_code' => 'receivable_plan',
                        'dst_module_code' => 'contract',
                        'type' => 'belong_to',
                        'link_id' => ['contract_id']
                    ],
                    [ // 回款计划所属项目
                        'src_module_code' => 'receivable_plan',
                        'dst_module_code' => 'project',
                        'type' => 'belong_to',
                        'link_id' => ['project_id']
                    ],
                    [ // 回款计划创建用户
                        'src_module_code' => 'receivable_plan',
                        'dst_module_code' => 'user',
                        'type' => 'belong_to',
                        'link_id' => ['created_by']
                    ]
                ]
            ],
            [
                'schema' => [
                    'name' => '结算模块模型',
                    'code' => 'settlement',
                    'type' => 'system',
                    'uuid' => Webpatser\Uuid\Uuid::generate()->string
                ],
                'module_relation' => [
                    [ // 结算所属合同
                        'src_module_code' => 'settlement',
                        'dst_module_code' => 'contract',
                        'type' => 'belong_to',
                        'link_id' => ['contract_id']
                    ],
                    [ // 结算所属订单
                        'src_module_code' => 'settlement',
                        'dst_module_code' => 'order',
                        'type' => 'belong_to',
                        'link_id' => ['order_id']
                    ],
                    [ // 结算所属项目
                        'src_module_code' => 'settlement',
                        'dst_module_code' => 'project',
                        'type' => 'belong_to',
                        'link_id' => ['project_id']
                    ],
                    [ // 结算创建用户
                        'src_module_code' => 'settlement',
                        'dst_module_code' => 'user',
                        'type' => 'belong_to',
                        'link_id' => ['created_by']
                    ]
                ]
            ],
            [
                'schema' => [
                    'name' => '回款模块模型',
                    'code' => 'receivable',
                    'type' => 'system',
                    'uuid' => Webpatser\Uuid\Uuid::generate()->string
                ],
                'module_relation' => [
                    [ // 回款所属合同
                        'src_module_code' => 'receivable',
                        'dst_module_code' => 'contract',
                        'type' => 'belong_to',
                        'link_id' => ['contract_id']
                    ],
                    [ // 回款所属订单
                        'src_module_code' => 'receivable',
                        'dst_module_code' => 'order',
                        'type' => 'belong_to',
                        'link_id' => ['order_id']
                    ],
                    [ // 回款所属结算
                        'src_module_code' => 'receivable',
                        'dst_module_code' => 'settlement',
                        'type' => 'belong_to',
                        'link_id' => ['settlement_id']
                    ],
                    [ // 回款所属项目
                        'src_module_code' => 'receivable',
                        'dst_module_code' => 'project',
                        'type' => 'belong_to',
                        'link_id' => ['project_id']
                    ],
                    [ // 回款创建用户
                        'src_module_code' => 'receivable',
                        'dst_module_code' => 'user',
                        'type' => 'belong_to',
                        'link_id' => ['created_by']
                    ]
                ]
            ],
            [
                'schema' => [
                    'name' => '发票模块模型',
                    'code' => 'invoice',
                    'type' => 'system',
                    'uuid' => Webpatser\Uuid\Uuid::generate()->string
                ],
                'module_relation' => [
                    [ // 发票所属订单
                        'src_module_code' => 'invoice',
                        'dst_module_code' => 'order',
                        'type' => 'belong_to',
                        'link_id' => ['order_id']
                    ],
                    [ // 发票所属回款
                        'src_module_code' => 'invoice',
                        'dst_module_code' => 'receivable',
                        'type' => 'belong_to',
                        'link_id' => ['receivable_id']
                    ]
                ]
            ]
        ];


        // 写入数据库
        $schemaTable = $this->table('schema');
        $moduleRelationTable = $this->table('module_relation');

        foreach ($schemaConfig as $schemaItem) {
            // 先写入schema
            $schemaItem["schema"]['module_id'] = $moduleMap[$schemaItem["schema"]['code']]['id'];
            $schemaTable->insert($schemaItem["schema"])->save();


            // 获取当前写入schema id
            $query = $this->fetchRow('SELECT max(`id`) as id FROM `schema`');

            foreach ($schemaItem["module_relation"] as $moduleRelationItem) {
                $moduleRelationData = $this->generateNodeConfig($query['id'], $moduleRelationItem, $moduleMap);
                $moduleRelationTable->insert($moduleRelationData)->save();
            }
        }
    }

    /**
     * 生成关联节点配置
     * @param $schemaId
     * @param $moduleRelationConfig
     * @param $moduleMap
     * @return array
     * @throws Exception
     */
    public function generateNodeConfig($schemaId, $moduleRelationConfig, $moduleMap)
    {
        $config = [
            'type' => $moduleRelationConfig['type'],
            'src_module_id' => $moduleMap[$moduleRelationConfig['src_module_code']]['id'],
            'dst_module_id' => $moduleMap[$moduleRelationConfig['dst_module_code']]['id'],
            'link_id' => join(',', $moduleRelationConfig['link_id']),
            'schema_id' => $schemaId,
            'uuid' => Webpatser\Uuid\Uuid::generate()->string,
            'node_config' => json_encode([
                "edges" => [
                    "data" => [
                        "type" => "connection",
                        "label" => $moduleRelationConfig['type']
                    ],
                    "source" => $moduleMap[$moduleRelationConfig['src_module_code']]['uuid'],
                    "target" => $moduleMap[$moduleRelationConfig['dst_module_code']]['uuid']
                ],
                "node_data" => [
                    "source" => [
                        "h" => "80px",
                        "w" => "120px",
                        "id" => $moduleMap[$moduleRelationConfig['src_module_code']]['uuid'],
                        "top" => "147px",
                        "left" => "405px",
                        "name" => ucfirst($moduleRelationConfig['src_module_code']),
                        "type" => "module",
                        "icon" => "",
                        "module_id" => $moduleMap[$moduleRelationConfig['src_module_code']]['id'],
                        "module_code" => $moduleRelationConfig['src_module_code'],
                        "module_type" => $moduleMap[$moduleRelationConfig['src_module_code']]['type']
                    ],
                    "target" => [
                        "h" => "80px",
                        "w" => "120px",
                        "id" => $moduleMap[$moduleRelationConfig['dst_module_code']]['uuid'],
                        "top" => "387px",
                        "left" => "229px",
                        "name" => ucfirst($moduleRelationConfig['dst_module_code']),
                        "type" => "module",
                        "icon" => "",
                        "module_id" => $moduleMap[$moduleRelationConfig['dst_module_code']]['id'],
                        "module_code" => $moduleRelationConfig['dst_module_code'],
                        "module_type" => $moduleMap[$moduleRelationConfig['dst_module_code']]['type']
                    ]
                ]
            ])
        ];

        return $config;
    }

    /**
     * Migrate Down.
     */
    function down()
    {
        $this->execute('DELETE FROM schema');
        $this->execute('DELETE FROM module_relation');
    }
}
